package cn.wolfcode.business.service.impl;

import cn.wolfcode.business.domain.BusAppointment;
import cn.wolfcode.business.domain.BusStatement;
import cn.wolfcode.business.domain.BusStatementItem;
import cn.wolfcode.business.domain.vo.StatementItemVO;
import cn.wolfcode.business.mapper.BusStatementItemMapper;
import cn.wolfcode.business.service.IBusAppointmentService;
import cn.wolfcode.business.service.IBusStatementItemService;
import cn.wolfcode.business.service.IBusStatementService;
import cn.wolfcode.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 结算单明细Service业务层处理
 * 
 * @author wolfcode
 * @date 2025-09-23
 */
@Service
public class BusStatementItemServiceImpl implements IBusStatementItemService 
{
    @Autowired
    private BusStatementItemMapper busStatementItemMapper;  // 结算单明细 Mapper
    @Autowired
    private IBusStatementService statementService;  // 结算单 Service
    @Autowired
    private IBusAppointmentService appointmentService;  // 预约单 Service

    /**
     * 保存功能
     * @param vo 结算单折扣价   结算单明细集合
     * @return 结果
     */
    @Override
    @Transactional
    public int statementItemSave(StatementItemVO vo) {
        // 数据合理性校验
        if(vo == null || vo.getDiscountPrice() == null || vo.getStatementItemList() == null
            || vo.getStatementItemList().isEmpty()){
            throw new RuntimeException("非法参数");
        }
        // 在结算单明细中拿到第一条数据中的 statementId。做为我们结算单 id
        Long statementId = vo.getStatementItemList().get(0).getStatementId();
        // 若当前结合为 Null，则清空
//        if(vo.getStatementItemList().isEmpty()){
//            busStatementItemMapper.deleteRelationStatementItemByStatementId(statementId);
//        }
        // 根据获取到的结算单 id 查询结算单对象
        BusStatement statement = statementService.selectBusStatementById(statementId);
        // 对查询到的对象进行验证
        if(statement == null){
            throw new RuntimeException("非法参数");
        }
        // 判断结算单状态，必须是消费中才可以进行保存操作
        if(BusStatement.STATUS_PAID.equals(statement.getStatus())){
            throw new RuntimeException("只有消费中的结算单才可以进行保存操作");
        }
        // 删除旧的当前结算单对应的结算单明细数据
        busStatementItemMapper.deleteRelationStatementItemByStatementId(statementId);
        // 总价格
        BigDecimal totalAmount = new BigDecimal("0");
        // 总数量
        BigDecimal totalQuantity = new BigDecimal("0");
        // 折扣价
        BigDecimal discountAmount = vo.getDiscountPrice();
        // 循环遍历我们的结算单明细集合 计算总价格，总数量
        for(BusStatementItem statementItem : vo.getStatementItemList()){
            // 计算总价格
            totalAmount =
                    totalAmount.add(statementItem.getItemPrice().multiply(new BigDecimal(statementItem.getItemQuantity())));
            // 计算总数量
            totalQuantity = totalQuantity.add(new BigDecimal(statementItem.getItemQuantity()));
        }
        // 验证总价格和总数量
        // 总价格 >= 0 && 折扣价 >=0 && 总价格 >= 折扣价
        if(!(totalAmount.compareTo(new BigDecimal("0")) >= 0
            && discountAmount.compareTo(new BigDecimal("0")) >= 0
            && totalAmount.compareTo(discountAmount) >= 0)){
            throw new RuntimeException("总价格大于0，且优惠价大于0，且总价格需要大于折扣价");
        }
        // 验证总数量 > 0
        if(totalQuantity.compareTo(new BigDecimal("0")) <= 0){
            throw new RuntimeException("总数量必须大于0");
        }
        // 更新结算单
        statementService.updateAmount(statementId,totalAmount,totalQuantity,discountAmount);
        // 批量插入结算单明细
        return busStatementItemMapper.insertStatementItemBatch(vo.getStatementItemList());
    }

    /**
     * 根据结算单 Id 查询结算单明细列表
     * @param statementId 结算单id
     * @return 结算单明细集合
     */
    @Override
    public List<BusStatementItem> selectList(Long statementId) {
        BusStatementItem statementItem = new BusStatementItem();
        statementItem.setStatementId(statementId);
        return busStatementItemMapper.selectBusStatementItemList(statementItem);
    }

    /**
     * 结算单支付功能
     * @param statementId 结算单 id
     * @return 结果
     */
    @Override
    @Transactional
    public int pay(Long statementId) {
        // 参数合理化验证
        if (statementId == null) {
            throw new RuntimeException("非法参数");
        }
        // 根据结算单 id 查询结算单对象
        BusStatement statement = statementService.selectBusStatementById(statementId);
        if(statement == null){
            throw new RuntimeException("非法参数");
        }
        // 验证结算单状态必须是消费中才可以进行支付操作
        if(BusStatement.STATUS_PAID.equals(statement.getStatus())){
            throw new RuntimeException("只有消费中的结算单才可以进行支付操作");
        }
        // 判断该结算单是否由预约单生成。
        if(statement.getAppointmentId() != null){
            // 存在预约单 id，说明是预约用户，我们需要将预约单的状态也修改为已支付。（说明该结算单存在关联的预约单）
            appointmentService.updateStatus(statement.getAppointmentId(), BusAppointment.STATUS_PAID);
        }
        // 根据结算单 id 修改结算单状态为已支付，同时添加收款人和收款时间
        Long payId = SecurityUtils.getUserId();
        return statementService.updatePayStatus(statementId,payId,new Date(),BusStatement.STATUS_PAID);
    }
}
